Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Property filter groups phase 1 #2454

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"files": [],
"scripts": {
"quick-build": "gulp quick-build",
"postinstall": "node ./scripts/install-peer-dependency.js collection-hooks:property-filter-token-groups",
"build": "cross-env NODE_ENV=production gulp build",
"test": "TZ=UTC gulp test",
"test:unit": "TZ=UTC gulp test:unit",
Expand Down Expand Up @@ -158,4 +159,4 @@
"last 3 Edge major versions",
"last 3 Safari major versions"
]
}
}
6 changes: 3 additions & 3 deletions pages/property-filter/common-props.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,9 @@ export const columnDefinitions = [
{
id: 'lasteventat',
sortingField: 'lasteventat',
header: 'Last event occurrence',
header: 'Last event at',
type: 'datetime',
propertyLabel: 'Last event occurrence',
propertyLabel: 'Last event at',
cell: (item: TableItem) => item.lasteventat?.toISOString(),
},
].map((item, ind) => ({ order: ind + 1, ...item }));
Expand Down Expand Up @@ -164,7 +164,7 @@ export const i18nStrings: PropertyFilterProps.I18nStrings = {
tokenLimitShowFewer: 'Show fewer',
clearFiltersText: 'Clear filters',
tokenOperatorAriaLabel: 'Boolean Operator',
removeTokenButtonAriaLabel: () => 'Remove token',
removeTokenButtonAriaLabel: token => `remove filter ${token.propertyKey}`,
enteredTextLabel: (text: string) => `Use: "${text}"`,
};

Expand Down
95 changes: 95 additions & 0 deletions pages/property-filter/demo.page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import React from 'react';
import AppLayout from '~components/app-layout';
import Box from '~components/box';
import Table from '~components/table';
import PropertyFilter from '~components/property-filter';
import Header from '~components/header';
import Button from '~components/button';
import ScreenshotArea from '../utils/screenshot-area';
import { Navigation, Breadcrumbs } from '../app-layout/utils/content-blocks';
import labels from '../app-layout/utils/labels';
import { allItems, states, TableItem } from './table.data';
import { columnDefinitions, i18nStrings, filteringProperties } from './common-props';
import { useCollection } from '@cloudscape-design/collection-hooks';

export default function () {
const { items, collectionProps, actions, propertyFilterProps } = useCollection(allItems, {
propertyFiltering: {
empty: 'empty',
noMatch: (
<Box textAlign="center" color="inherit">
<Box variant="strong" textAlign="center" color="inherit">
No matches
</Box>
<Box variant="p" padding={{ bottom: 's' }} color="inherit">
We can’t find a match.
</Box>
<Button
onClick={() => actions.setPropertyFiltering({ tokens: [], operation: propertyFilterProps.query.operation })}
>
Clear filter
</Button>
</Box>
),
filteringProperties,
defaultQuery: {
tokens: [],
tokenGroups: [
{ propertyKey: 'state', operator: '=', value: '0' },
{
operation: 'and',
tokens: [
{ propertyKey: 'instancetype', operator: '!=', value: 't3.nano' },
{ propertyKey: 'averagelatency', operator: '<', value: '100' },
],
},
],
operation: 'or',
},
},
sorting: {},
});

const filteringOptions = propertyFilterProps.filteringOptions.map(option => {
if (option.propertyKey === 'state') {
option.label = states[parseInt(option.value)];
}
return option;
});

return (
<ScreenshotArea gutters={false}>
<AppLayout
ariaLabels={labels}
breadcrumbs={<Breadcrumbs />}
navigation={<Navigation />}
toolsHide={true}
content={
<Table<TableItem>
className="main-content"
stickyHeader={true}
header={<Header headingTagOverride={'h1'}>Instances</Header>}
items={items}
{...collectionProps}
filter={
<PropertyFilter
{...propertyFilterProps}
filteringOptions={filteringOptions}
virtualScroll={true}
countText={`${items.length} matches`}
i18nStrings={i18nStrings}
expandToViewport={true}
filteringEmpty="No properties"
enableTokenGroups={true}
tokenLimit={2}
/>
}
columnDefinitions={columnDefinitions.slice(0, 2)}
/>
}
/>
</ScreenshotArea>
);
}
35 changes: 24 additions & 11 deletions pages/property-filter/permutations.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,24 +130,37 @@ const permutations = createPermutations<Partial<PropertyFilterProps>>([
},
]);

const groupPermutations = permutations.map(permutation => {
const query = permutation.query ?? { operation: 'and', tokens: [] };
query.tokenGroups = [{ operation: query.operation === 'and' ? 'or' : 'and', tokens: query.tokens }];
return { ...permutation, enableTokenGroups: true };
});

export default function () {
const commonProps = {
countText: '5 matches',
i18nStrings,
query: { operation: 'and', tokens: [] },
onChange: () => {},
filteringProperties,
filteringOptions,
} as const;
return (
<>
<h1>Token visuals screenshot page</h1>
<ScreenshotArea disableAnimations={true}>
<PermutationsView
permutations={permutations}
render={permutation => (
<PropertyFilter
countText={`5 matches`}
i18nStrings={i18nStrings}
query={{ tokens: [], operation: 'and' }}
onChange={() => {}}
filteringProperties={filteringProperties}
filteringOptions={filteringOptions}
{...permutation}
/>
)}
render={permutation => <PropertyFilter {...commonProps} {...permutation} />}
/>
<br />
<br />
<hr />
<br />
<br />
<PermutationsView
permutations={groupPermutations}
render={permutation => <PropertyFilter {...commonProps} {...permutation} />}
/>
</ScreenshotArea>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,19 @@ export default function () {
</Box>
),
filteringProperties,
defaultQuery: { tokens: [{ propertyKey: 'averagelatency', operator: '!=', value: '30' }], operation: 'and' },
defaultQuery: {
tokens: [],
tokenGroups: [
{
operation: 'or',
tokens: [
{ propertyKey: 'state', operator: '=', value: '0' },
{ propertyKey: 'state', operator: '=', value: '1' },
],
},
],
operation: 'or',
},
},
sorting: {},
});
Expand Down
55 changes: 55 additions & 0 deletions scripts/install-peer-dependency.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/env node
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

const { execSync } = require('child_process');
const path = require('path');
const os = require('os');

const args = process.argv.slice(2);
if (args.length < 1) {
console.error('Usage: install-peer-dependency.js <package-name>:<target-branch>');
process.exit(1);
}
const [packageName, targetBranch] = args[0].split(':');
const targetRepository = `https://github.com/cloudscape-design/${packageName}.git`;
const nodeModulesPackagePath = path.join(__dirname, '..', 'node_modules', '@cloudscape-design', packageName);
const tempDir = path.join(os.tmpdir(), `temp-${packageName}`);

// Clone the repository and checkout the branch
console.log(`Cloning ${packageName}:${targetBranch}...`);
execCommand(`git clone ${targetRepository} ${tempDir}`);
process.chdir(tempDir);
execCommand(`git checkout ${targetBranch}`);

// Install dependencies and build
console.log(`Installing dependencies and building ${packageName}...`);
execCommand('npm install');
execCommand('npm run build');

// Remove existing peer dependency in node_modules
console.log(`Removing existing ${packageName} from node_modules...`);
execCommand(`rm -rf ${nodeModulesPackagePath}`);

// Copy built peer dependency to node_modules
console.log(`Copying built ${targetRepository} to node_modules...`);
execCommand(`mkdir -p ${nodeModulesPackagePath}`);
execCommand(`cp -R ${tempDir}/lib/* ${nodeModulesPackagePath}`);

// Clean up
console.log('Cleaning up...');
execCommand(`rm -rf ${tempDir}`);

console.log(`${packageName} has been successfully installed from branch ${targetBranch}!`);

function execCommand(command, options = {}) {
try {
execSync(command, { stdio: 'inherit', ...options });
Dismissed Show dismissed Hide dismissed
} catch (error) {
console.error(`Error executing command: ${command}`);
console.error(`Error message: ${error.message}`);
console.error(`Stdout: ${error.stdout && error.stdout.toString()}`);
console.error(`Stderr: ${error.stderr && error.stderr.toString()}`);
throw error;
}
}
Loading
Loading