@digital-ai/dot-components 3.11.1 → 3.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.esm.js CHANGED
@@ -8806,49 +8806,6 @@ function request(options) {
8806
8806
  });
8807
8807
  }
8808
8808
 
8809
- class CategoriesService {
8810
- /**
8811
- * Get a list of Categories by Application type.
8812
- * Return a list of Categories by Application type.
8813
- * @returns AllCategoriesResponse OK
8814
- * @returns Error Default error response
8815
- * @throws ApiError
8816
- */
8817
- static getCategoriesService() {
8818
- return __awaiter(this, void 0, void 0, function* () {
8819
- const result = yield request({
8820
- method: 'GET',
8821
- path: `/metadata/bi/categories`,
8822
- errors: {
8823
- 401: `Could not resolve a valid Tenant from the provided API Token.`
8824
- }
8825
- });
8826
- return result.body;
8827
- });
8828
- }
8829
- /**
8830
- * Get Categories for a single application type.
8831
- * Return all Categories for a single application type.
8832
- * @param appType
8833
- * @returns CategoriesResponse OK
8834
- * @returns Error Default error response
8835
- * @throws ApiError
8836
- */
8837
- static getCategoriesService1(appType) {
8838
- return __awaiter(this, void 0, void 0, function* () {
8839
- const result = yield request({
8840
- method: 'GET',
8841
- path: `/metadata/bi/categories/${appType}`,
8842
- errors: {
8843
- 400: `Given app type is not valid.`,
8844
- 401: `Could not resolve a valid Tenant from the provided API Token.`
8845
- }
8846
- });
8847
- return result.body;
8848
- });
8849
- }
8850
- }
8851
-
8852
8809
  class DashboardsService {
8853
8810
  /**
8854
8811
  * Get a list of Dashboards.
@@ -8858,8 +8815,8 @@ class DashboardsService {
8858
8815
  * @param sort Sort ordering to apply to the query.
8859
8816
  * @param filter List of filters (each filter is a separate query param, and they are OR'ed).
8860
8817
  *
8861
- * * **Filterable field names**: author_fullname, author_id, bi_type, categories, created_dt, description, external_embedding_id, external_id, id, is_ootb_dashboard, lifecycle_state, name, target_apps, updated_dt
8862
- * * **Searchable field names**: author_fullname, categories, description, name
8818
+ * * **Filterable field names**: author_fullname, author_id, bi_type, categories, created_dt, description, external_embedding_id, external_id, id, is_ootb_dashboard, lifecycle_state, name, target_apps, updated_by_fullname, updated_by_id, updated_dt
8819
+ * * **Searchable field names**: author_fullname, categories, description, name, updated_by_fullname
8863
8820
  *
8864
8821
  * @param favorite Boolean flag to only return dashboards marked as favorites.
8865
8822
  * @param q Case-insensitive search of all text fields.
@@ -9100,25 +9057,31 @@ class DashboardsService {
9100
9057
  }
9101
9058
  /**
9102
9059
  * Get Metadata (categories and authors)
9103
- * Return all Metadata for the given query parameters: bi_type, lifecycle_state, target_app, and/or is_ootb_dashboard
9060
+ * Return all Metadata for dashboards optionally filtered by the given parameters
9061
+ * @param filter List of filters (each filter is a separate query param, and they are OR'ed).
9062
+ *
9063
+ * * **Filterable field names**: author_fullname, bi_type, categories, created_dt, description, is_ootb_dashboard, lifecycle_state, name, updated_by_fullname, updated_dt
9064
+ * * **Searchable field names**: author_fullname, categories, description, name
9065
+ *
9066
+ * @param targetApp String match on the Dashboard target application - 'AGILITY', 'CONTINUOUSTEST', 'DEPLOY', 'RELEASE' or 'TEAMFORGE'.
9104
9067
  * @param biType String match on Dashboard bi type - 'MICROSTRATEGY'.
9105
9068
  * @param isOotbDashboard Boolean match on Dashboard OOTB status.
9106
9069
  * @param lifecycleState String match on Dashboard lifecycle state - 'DRAFT' or 'PUBLISHED'.
9107
- * @param targetApp String match on the Dashboard target application - 'AGILITY', 'CONTINUOUSTEST', 'DEPLOY' or 'RELEASE'.
9108
9070
  * @returns MetadataResponse OK
9109
9071
  * @returns Error Default error response
9110
9072
  * @throws ApiError
9111
9073
  */
9112
- static getDashboardsService2(biType = 'MICROSTRATEGY', isOotbDashboard = null, lifecycleState = null, targetApp = null) {
9074
+ static getDashboardsMetadata(filter, targetApp = null, biType = 'MICROSTRATEGY', isOotbDashboard = null, lifecycleState = null) {
9113
9075
  return __awaiter(this, void 0, void 0, function* () {
9114
9076
  const result = yield request({
9115
9077
  method: 'GET',
9116
9078
  path: `/metadata/bi/dashboards/metadata`,
9117
9079
  query: {
9080
+ filter: filter,
9081
+ target_app: targetApp,
9118
9082
  bi_type: biType,
9119
9083
  is_ootb_dashboard: isOotbDashboard,
9120
- lifecycle_state: lifecycleState,
9121
- target_app: targetApp
9084
+ lifecycle_state: lifecycleState
9122
9085
  },
9123
9086
  errors: {
9124
9087
  400: `Given query params are not valid.`,
@@ -9269,7 +9232,7 @@ const helpContent = {
9269
9232
  id: 'test-help-content-1',
9270
9233
  content: '<html><h1>Test</h1></html>'
9271
9234
  };
9272
- ({
9235
+ const dashboard1 = {
9273
9236
  author_fullname: 'Dashboard1 Author',
9274
9237
  author_id: 'id1a',
9275
9238
  target_apps: ['AGILITY'],
@@ -9294,8 +9257,8 @@ const helpContent = {
9294
9257
  help_content_id: helpContent.id,
9295
9258
  filter_configuration: [],
9296
9259
  favorite: false
9297
- });
9298
- ({
9260
+ };
9261
+ const dashboard2 = {
9299
9262
  author_fullname: 'Dashboard2 Author',
9300
9263
  author_id: 'id2a',
9301
9264
  target_apps: ['AGILITY'],
@@ -9318,8 +9281,8 @@ const helpContent = {
9318
9281
  help_content_id: helpContent.id,
9319
9282
  filter_configuration: [],
9320
9283
  favorite: true
9321
- });
9322
- ({
9284
+ };
9285
+ const dashboard3 = {
9323
9286
  author_fullname: 'Dashboard3 Author',
9324
9287
  author_id: 'id3a',
9325
9288
  target_apps: ['AGILITY'],
@@ -9342,7 +9305,7 @@ const helpContent = {
9342
9305
  help_content_id: helpContent.id,
9343
9306
  filter_configuration: [],
9344
9307
  favorite: false
9345
- });
9308
+ };
9346
9309
  const getCategoriesMock = {
9347
9310
  categories: {
9348
9311
  AGILITY: ['Scrum Master', 'DevOps Manager', 'Release Train Engineer', 'Agility Analytics'],
@@ -9352,6 +9315,16 @@ const getCategoriesMock = {
9352
9315
  TEAMFORGE: ['Scrum Master']
9353
9316
  }
9354
9317
  };
9318
+ const getAuthorsMock = [{
9319
+ id: dashboard1.author_id,
9320
+ full_name: dashboard1.author_fullname
9321
+ }, {
9322
+ id: dashboard2.author_id,
9323
+ full_name: dashboard2.author_fullname
9324
+ }, {
9325
+ id: dashboard3.author_id,
9326
+ full_name: dashboard3.author_fullname
9327
+ }];
9355
9328
  const accountId = 'acct1';
9356
9329
  const applicationId = 'app1';
9357
9330
  const nullStr = null;
@@ -9412,6 +9385,9 @@ function updateItemInArray(elements, updatedItem, idProp) {
9412
9385
  }
9413
9386
  return elements;
9414
9387
  }
9388
+ const authorSort = (a, b) => a.full_name.localeCompare(b.full_name);
9389
+ const categorySort = (a, b) => a.localeCompare(b);
9390
+ const metadataKey = isPublishedOnly => isPublishedOnly ? 'published' : 'all';
9415
9391
  const handleUpdateDashboard = (dashboards, updatedDashboard) => {
9416
9392
  updateItemInArray(dashboards, updatedDashboard, ID);
9417
9393
  return dashboards;
@@ -9440,18 +9416,37 @@ const DotMetadataApiProvider = ({
9440
9416
  cancelablePromise
9441
9417
  } = useCancelablePromise();
9442
9418
  const [accountId, setAccountId] = useState(accountOverrideId);
9443
- const [categories, setCategories] = useState(null);
9444
- const [categoriesLoading, setCategoriesLoading] = useState(true);
9445
9419
  const [dashboards, setDashboards] = useState();
9446
9420
  const [dashboardsLoading, setDashboardsLoading] = useState(true);
9421
+ const [metadata, setMetadata] = useState(null);
9422
+ const [metadataLoading, setMetadataLoading] = useState(true);
9447
9423
  const [helpContentLoading, setHelpContentLoading] = useState(true);
9448
9424
  const [openedDashboardDetails, setOpenedDashboardDetails] = useState(null);
9449
9425
  const [dashboardsError, setDashboardsError] = useState(null);
9450
9426
  const [platformConsoleUrl, setPlatformConsoleUrl] = useState(null);
9451
9427
  const MOCK_API_URL = 'https://demo-mock-api';
9428
+ const retrieveMetadata = useCallback((appType, isPublishedOnly) => {
9429
+ setMetadataLoading(true);
9430
+ return cancelablePromise(DashboardsService.getDashboardsMetadata(undefined, appType, undefined, undefined, isPublishedOnly ? 'PUBLISHED' : undefined)).then(response => {
9431
+ setMetadataLoading(false);
9432
+ setDashboardsError(null);
9433
+ const key = metadataKey(isPublishedOnly);
9434
+ setMetadata(orig => {
9435
+ const appTypeMetadata = orig && appType in orig ? Object.assign({}, orig[appType]) : {};
9436
+ appTypeMetadata[key] = response;
9437
+ return Object.assign(Object.assign({}, orig), {
9438
+ [appType]: appTypeMetadata
9439
+ });
9440
+ });
9441
+ return response;
9442
+ }).catch(error => {
9443
+ setMetadataLoading(false);
9444
+ setDashboardsError(error);
9445
+ return null;
9446
+ });
9447
+ }, []);
9452
9448
  const memoizedValues = useMemo(() => ({
9453
- categories,
9454
- categoriesLoading,
9449
+ metadataLoading,
9455
9450
  dashboardsError,
9456
9451
  dashboardsLoading,
9457
9452
  helpContentLoading,
@@ -9547,25 +9542,64 @@ const DotMetadataApiProvider = ({
9547
9542
  return response;
9548
9543
  }).catch(error => setDashboardsError(error));
9549
9544
  }),
9550
- getCategories: () => __awaiter(void 0, void 0, void 0, function* () {
9551
- setCategoriesLoading(true);
9552
- if (OpenAPI.BASE === MOCK_API_URL) {
9545
+ getAuthors: (appType, isPublishedOnly = false) => {
9546
+ const key = metadataKey(isPublishedOnly);
9547
+ if (metadata && appType in metadata) {
9548
+ const appTypeMetadata = metadata[appType];
9549
+ if (key in appTypeMetadata) {
9550
+ appTypeMetadata[key]['authors'].sort(authorSort);
9551
+ return Promise.resolve(appTypeMetadata[key]['authors']);
9552
+ }
9553
+ } else if (OpenAPI.BASE === MOCK_API_URL) {
9553
9554
  setDashboardsError(null);
9554
- setCategoriesLoading(false);
9555
- setCategories(getCategoriesMock);
9556
- return getCategoriesMock;
9557
- } else {
9558
- return cancelablePromise(CategoriesService.getCategoriesService()).then(response => {
9559
- setDashboardsError(null);
9560
- setCategoriesLoading(false);
9561
- setCategories(response);
9562
- return response;
9563
- }).catch(error => {
9564
- setCategoriesLoading(false);
9565
- setDashboardsError(error);
9566
- return null;
9555
+ setMetadataLoading(false);
9556
+ return Promise.resolve(appType == 'AGILITY' ? getAuthorsMock : []);
9557
+ }
9558
+ return cancelablePromise(retrieveMetadata(appType, isPublishedOnly)).then(response => {
9559
+ response.authors.sort(authorSort);
9560
+ return response.authors;
9561
+ });
9562
+ },
9563
+ getCategories: (appType, isPublishedOnly = false) => __awaiter(void 0, void 0, void 0, function* () {
9564
+ const key = metadataKey(isPublishedOnly);
9565
+ if (metadata && appType in metadata) {
9566
+ const appTypeMetadata = metadata[appType];
9567
+ if (key in appTypeMetadata) {
9568
+ appTypeMetadata[key]['categories'].sort(categorySort);
9569
+ return Promise.resolve(appTypeMetadata[key]['categories']);
9570
+ }
9571
+ } else if (OpenAPI.BASE === MOCK_API_URL) {
9572
+ setDashboardsError(null);
9573
+ setMetadataLoading(false);
9574
+ const categories = getCategoriesMock.categories[appType];
9575
+ setMetadata(orig => {
9576
+ if (orig && appType in orig) {
9577
+ const appTypeCategories = orig[appType];
9578
+ appTypeCategories[key]['categories'] = categories;
9579
+ return Object.assign(Object.assign({}, orig), {
9580
+ [appType]: appTypeCategories
9581
+ });
9582
+ }
9583
+ return orig ? Object.assign(Object.assign({}, orig), {
9584
+ [appType]: {
9585
+ [key]: {
9586
+ categories
9587
+ }
9588
+ }
9589
+ }) : {
9590
+ [appType]: {
9591
+ [key]: {
9592
+ categories
9593
+ }
9594
+ }
9595
+ };
9567
9596
  });
9597
+ return Promise.resolve(categories);
9568
9598
  }
9599
+ return cancelablePromise(retrieveMetadata(appType, isPublishedOnly)).then(response => {
9600
+ response === null || response === void 0 ? void 0 : response.categories.sort(categorySort);
9601
+ return response === null || response === void 0 ? void 0 : response.categories;
9602
+ });
9569
9603
  }),
9570
9604
  getDashboardHelpContent: helpContentId => __awaiter(void 0, void 0, void 0, function* () {
9571
9605
  setHelpContentLoading(true);
@@ -9584,7 +9618,7 @@ const DotMetadataApiProvider = ({
9584
9618
  });
9585
9619
  }
9586
9620
  })
9587
- }), [categories, categoriesLoading, dashboardsError, dashboardsLoading, openedDashboardDetails, platformConsoleUrl]);
9621
+ }), [metadata, metadataLoading, dashboardsError, dashboardsLoading, openedDashboardDetails, platformConsoleUrl]);
9588
9622
  if (apiUrl && OpenAPI.BASE !== apiUrl) {
9589
9623
  OpenAPI.BASE = apiUrl;
9590
9624
  }
@@ -9925,6 +9959,18 @@ const StyledDashboardDetails = styled(DotDrawer)`
9925
9959
  `}
9926
9960
  `;
9927
9961
 
9962
+ const getFormattedDate = dateString => {
9963
+ if (!dateString) {
9964
+ return '';
9965
+ }
9966
+ const date = new Date(dateString);
9967
+ return date.toLocaleDateString('en-US', {
9968
+ dateStyle: 'medium'
9969
+ }) + ' - ' + date.toLocaleTimeString('en-US', {
9970
+ hour: '2-digit',
9971
+ minute: '2-digit'
9972
+ });
9973
+ };
9928
9974
  const DashboardDetailsField = ({
9929
9975
  children,
9930
9976
  className,
@@ -10086,11 +10132,11 @@ const DotDashboardDetailsView = ({
10086
10132
  }), jsx(DashboardDetailsField, {
10087
10133
  className: "dashboard-details-created-dt",
10088
10134
  label: "Created on",
10089
- value: dashboard.created_dt
10135
+ value: getFormattedDate(dashboard.created_dt)
10090
10136
  }), dashboard.updated_dt && jsx(DashboardDetailsField, {
10091
10137
  className: "dashboard-details-updated-dt",
10092
10138
  label: "Modified on",
10093
- value: dashboard.updated_dt
10139
+ value: getFormattedDate(dashboard.updated_dt)
10094
10140
  }), dashboard.updated_by_fullname && jsx(DashboardDetailsField, {
10095
10141
  className: "dashboard-details-updated-by",
10096
10142
  label: "Modified by",
@@ -10153,6 +10199,41 @@ const DotDashboardDetails = _a => {
10153
10199
  return null;
10154
10200
  };
10155
10201
 
10202
+ function DashboardCategoriesAutoComplete(_a) {
10203
+ var {
10204
+ freesolo: _freesolo,
10205
+ actionItem: _actionItem,
10206
+ onInputChange,
10207
+ onNewCategory
10208
+ } = _a,
10209
+ args = __rest(_a, ["freesolo", "actionItem", "onInputChange", "onNewCategory"]);
10210
+ const getActionItemNode = value => {
10211
+ return value ? jsxs("span", {
10212
+ children: ["Create new ", jsx("strong", {
10213
+ children: value
10214
+ }), " category"]
10215
+ }) : 'Enter a label to create new category';
10216
+ };
10217
+ const [actionItemText, setActionItemText] = useState(getActionItemNode(''));
10218
+ const handleActionItemClick = newItem => {
10219
+ if (newItem && onNewCategory) {
10220
+ onNewCategory(newItem);
10221
+ }
10222
+ };
10223
+ const customActionItem = {
10224
+ text: actionItemText,
10225
+ onClick: handleActionItemClick
10226
+ };
10227
+ return jsx(DotAutoComplete, Object.assign({}, args, {
10228
+ freesolo: false,
10229
+ actionItem: customActionItem,
10230
+ onInputChange: (event, value, reason) => {
10231
+ setActionItemText(getActionItemNode(value));
10232
+ onInputChange && onInputChange(event, value, reason);
10233
+ }
10234
+ }));
10235
+ }
10236
+
10156
10237
  const DotInputSelect = ({
10157
10238
  ariaLabel,
10158
10239
  autoFocus,
@@ -10393,6 +10474,12 @@ function DotDashboardDialog({
10393
10474
  }));
10394
10475
  setIsDirty(true);
10395
10476
  }, [formValues]);
10477
+ const handleNewCategory = useCallback(newCategory => {
10478
+ setFormValues(orig => Object.assign(Object.assign({}, orig), {
10479
+ categories: [...categories, newCategory]
10480
+ }));
10481
+ setIsDirty(true);
10482
+ }, [categories]);
10396
10483
  const getCategoryValues = useCallback(() => categories.map(category => ({
10397
10484
  title: category
10398
10485
  })), [categories]);
@@ -10492,11 +10579,12 @@ function DotDashboardDialog({
10492
10579
  }), jsx(DotTypography, {
10493
10580
  variant: "body2",
10494
10581
  children: "Please select the appropriate categories"
10495
- }), jsx(DotAutoComplete, {
10582
+ }), jsx(DashboardCategoriesAutoComplete, {
10496
10583
  "data-testid": "dashboard-dialog-categories-input",
10497
10584
  filterSelectedOptions: true,
10498
10585
  inputId: "dashboard-dialog-categories-input",
10499
10586
  onChange: handleChangeCategories,
10587
+ onNewCategory: handleNewCategory,
10500
10588
  options: getAvailableCategoryOptions(),
10501
10589
  placeholder: "Select categories",
10502
10590
  label: "Category",
@@ -10586,7 +10674,6 @@ const productNameCategoryMap = {
10586
10674
  */
10587
10675
  function ActivePublishMessage({
10588
10676
  applicationList,
10589
- categories,
10590
10677
  dashboardName,
10591
10678
  initialCategories,
10592
10679
  published,
@@ -10598,6 +10685,9 @@ function ActivePublishMessage({
10598
10685
  const [appNameMap, setAppNameMap] = useState({});
10599
10686
  const [appNameMapLoading, setAppNameMapLoading] = useState(true);
10600
10687
  const [categoryOptions, setCategoryOptions] = useState([]);
10688
+ const {
10689
+ getCategories
10690
+ } = useDotMetadataApiContext();
10601
10691
  const appOptions = applicationList.map((application, index) => {
10602
10692
  return {
10603
10693
  title: application.name,
@@ -10616,23 +10706,24 @@ function ActivePublishMessage({
10616
10706
  }
10617
10707
  }, [applicationList]);
10618
10708
  useEffect(() => {
10619
- const selectedCategoryOptions = [];
10620
10709
  if (selectedApp) {
10621
10710
  if (selectedApp.logo_product_name in productNameCategoryMap) {
10711
+ const selectedCategoryOptions = [];
10622
10712
  const categoryKey = productNameCategoryMap[selectedApp.logo_product_name];
10623
- const appCategories = categories.categories[categoryKey];
10624
- const newCategoryOptions = appCategories.map(category => ({
10625
- title: category
10626
- }));
10627
- setCategoryOptions(newCategoryOptions);
10628
- selectedCategoryOptions.push(...newCategoryOptions.filter(o => initialCategories.includes(o.title)));
10713
+ getCategories(categoryKey).then(appCategories => {
10714
+ const newCategoryOptions = appCategories.map(category => ({
10715
+ title: category
10716
+ }));
10717
+ setCategoryOptions(newCategoryOptions);
10718
+ selectedCategoryOptions.push(...newCategoryOptions.filter(o => initialCategories.includes(o.title)));
10719
+ setSelectedCategories(selectedCategoryOptions);
10720
+ });
10629
10721
  } else {
10630
10722
  setCategoryOptions([]);
10631
10723
  }
10632
10724
  } else {
10633
10725
  setCategoryOptions([]);
10634
10726
  }
10635
- setSelectedCategories(selectedCategoryOptions);
10636
10727
  }, [selectedApp]);
10637
10728
  useEffect(() => {
10638
10729
  const selectedAppCategories = selectedCategories.map(c => c.title);
@@ -10657,6 +10748,11 @@ function ActivePublishMessage({
10657
10748
  const handleChangeCategories = useCallback((_event, options, _reason) => {
10658
10749
  setSelectedCategories(options);
10659
10750
  }, []);
10751
+ const handleNewCategory = useCallback(newCategory => {
10752
+ setSelectedCategories(orig => [...orig, {
10753
+ title: newCategory
10754
+ }]);
10755
+ }, [selectedCategories]);
10660
10756
  if (published) {
10661
10757
  return jsxs(StyledPublishConfirmDiv, {
10662
10758
  children: [jsxs(DotAlertBanner, {
@@ -10733,10 +10829,11 @@ function ActivePublishMessage({
10733
10829
  variant: "circular",
10734
10830
  size: "large"
10735
10831
  })]
10736
- }), (selectedApp === null || selectedApp === void 0 ? void 0 : selectedApp.logo_product_name) && selectedApp.logo_product_name in productNameCategoryMap && categories.categories[productNameCategoryMap[selectedApp.logo_product_name]].length > 0 && jsx(DotAutoComplete, {
10832
+ }), (categoryOptions === null || categoryOptions === void 0 ? void 0 : categoryOptions.length) > 0 && jsx(DashboardCategoriesAutoComplete, {
10737
10833
  "data-testid": "publish-categories-input",
10738
10834
  inputId: "publish-categories-input",
10739
10835
  onChange: handleChangeCategories,
10836
+ onNewCategory: handleNewCategory,
10740
10837
  options: categoryOptions,
10741
10838
  placeholder: "Select categories",
10742
10839
  value: selectedCategories,
@@ -10797,7 +10894,6 @@ function ActiveUnpublishMessage({
10797
10894
  }
10798
10895
  function DotDashboardPublishConfirm({
10799
10896
  applicationList,
10800
- categories,
10801
10897
  dashboardToPublish,
10802
10898
  dashboardToUnpublish,
10803
10899
  onClose,
@@ -10878,6 +10974,7 @@ function DotDashboardPublishConfirm({
10878
10974
  setPublishAppInstance(selectedApplication);
10879
10975
  setPublishCategories(selectedCategories);
10880
10976
  }, []);
10977
+ const canSubmit = publishAppInstance && !((publishAppInstance === null || publishAppInstance === void 0 ? void 0 : publishAppInstance.logo_product_name) && publishAppInstance.logo_product_name in productNameCategoryMap && publishCategories.length === 0);
10881
10978
  return jsxs(Fragment, {
10882
10979
  children: [dashboardToPublish !== null && jsx(DotDialog, {
10883
10980
  cancelButtonVisible: !published,
@@ -10887,14 +10984,13 @@ function DotDashboardPublishConfirm({
10887
10984
  title: "Publish to application",
10888
10985
  submitButtonProps: {
10889
10986
  'data-testid': 'publish-confirm-button',
10890
- disabled: publishAppInstance === null || (publishAppInstance === null || publishAppInstance === void 0 ? void 0 : publishAppInstance.logo_product_name) && publishAppInstance.logo_product_name in productNameCategoryMap && categories.categories[productNameCategoryMap[publishAppInstance.logo_product_name]].length > 0 && publishCategories.length === 0,
10987
+ disabled: !canSubmit,
10891
10988
  label: published ? 'Got it' : 'Publish'
10892
10989
  },
10893
10990
  onCancel: handleCancelPublish,
10894
10991
  onSubmit: published ? handleCancelPublish : handlePublish,
10895
10992
  children: jsx(ActivePublishMessage, {
10896
10993
  applicationList: filteredApplications,
10897
- categories: categories,
10898
10994
  dashboardName: dashboardToPublish === null || dashboardToPublish === void 0 ? void 0 : dashboardToPublish.name,
10899
10995
  initialCategories: publishCategories,
10900
10996
  published: published,
@@ -11127,7 +11223,6 @@ function CloseButton({
11127
11223
  }
11128
11224
  function DotDashboardActions({
11129
11225
  applications,
11130
- categories,
11131
11226
  dashboard,
11132
11227
  isEdit = false,
11133
11228
  canEdit = false,
@@ -11135,8 +11230,7 @@ function DotDashboardActions({
11135
11230
  onFavorite,
11136
11231
  onStatusChanged,
11137
11232
  onDuplicated,
11138
- onViewMode,
11139
- onDetails
11233
+ onViewMode
11140
11234
  }) {
11141
11235
  // NOTE: useState functions need to stay at the top of the file so that
11142
11236
  // they are evaluated before any context imports. If they are evaluated
@@ -11144,10 +11238,20 @@ function DotDashboardActions({
11144
11238
  const [dashboardToCopy, setDashboardToCopy] = useState(null);
11145
11239
  const [dashboardToPublish, setDashboardToPublish] = useState(null);
11146
11240
  const [dashboardToUnpublish, setDashboardToUnpublish] = useState(null);
11241
+ const [appCategories, setAppCategories] = useState(null);
11147
11242
  const {
11148
11243
  duplicateDashboard,
11244
+ getCategories,
11149
11245
  setOpenedDashboardDetails
11150
11246
  } = useDotMetadataApiContext();
11247
+ useEffect(() => {
11248
+ var _a;
11249
+ if (dashboard && ((_a = dashboard.target_apps) === null || _a === void 0 ? void 0 : _a.length) > 0) {
11250
+ getCategories(dashboard.target_apps[0]).then(categories => {
11251
+ setAppCategories(categories);
11252
+ });
11253
+ }
11254
+ }, [dashboard]);
11151
11255
  const handlePublishConfirm = useCallback(publishedDashboard => {
11152
11256
  setDashboardToPublish(null);
11153
11257
  setDashboardToUnpublish(null);
@@ -11186,14 +11290,13 @@ function DotDashboardActions({
11186
11290
  "data-testid": "dot-dashboard-actions",
11187
11291
  children: [jsx(DotDashboardPublishConfirm, {
11188
11292
  applicationList: applications,
11189
- categories: categories,
11190
11293
  dashboardToPublish: dashboardToPublish,
11191
11294
  dashboardToUnpublish: dashboardToUnpublish,
11192
11295
  onClose: handlePublishConfirmClose,
11193
11296
  onStatusChanged: handlePublishConfirm
11194
- }), categories && dashboardToCopy && jsx(DotDashboardDialog, {
11297
+ }), appCategories && dashboardToCopy && jsx(DotDashboardDialog, {
11195
11298
  title: "Duplicate dashboard",
11196
- availableCategories: categories === null || categories === void 0 ? void 0 : categories.categories[dashboard.target_apps[0]],
11299
+ availableCategories: appCategories,
11197
11300
  copyDashboard: dashboardToCopy,
11198
11301
  open: true,
11199
11302
  onClose: handleDuplicateClose,
@@ -11246,16 +11349,13 @@ function DotDashboardHeader({
11246
11349
  loadApplications
11247
11350
  } = useDotCoreApiContext();
11248
11351
  const {
11249
- categories,
11250
- categoriesLoading,
11251
- dashboardsError,
11252
- getCategories
11352
+ metadataLoading,
11353
+ dashboardsError
11253
11354
  } = useDotMetadataApiContext();
11254
11355
  useEnqueueErrorMessage(!applicationsLoading && applicationsError);
11255
- useEnqueueErrorMessage(!categoriesLoading && dashboardsError);
11356
+ useEnqueueErrorMessage(!metadataLoading && dashboardsError);
11256
11357
  useEffect(() => {
11257
11358
  loadApplications(accountId);
11258
- getCategories();
11259
11359
  }, []);
11260
11360
  return jsxs(StyledDashboardHeader, {
11261
11361
  children: [jsx(DotTypography, {
@@ -11264,7 +11364,6 @@ function DotDashboardHeader({
11264
11364
  children: dashboard === null || dashboard === void 0 ? void 0 : dashboard.name
11265
11365
  }), jsx(DotDashboardActions, {
11266
11366
  applications: applications,
11267
- categories: categories,
11268
11367
  dashboard: dashboard,
11269
11368
  isEdit: isEdit,
11270
11369
  canEdit: canEdit,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digital-ai/dot-components",
3
- "version": "3.11.1",
3
+ "version": "3.12.0",
4
4
  "private": false,
5
5
  "license": "SEE LICENSE IN <LICENSE.md>",
6
6
  "contributors": [
@@ -1,12 +1,10 @@
1
1
  import { ApplicationModel } from '../../core-api/openapi';
2
- import { AllCategories } from '../metadata-api/MetadataApiProvider';
3
2
  import { DashboardView } from '../metadata-api/openapi/';
4
3
  interface DashboardActionsCommonProps {
5
4
  canEdit?: boolean;
6
5
  dashboard: DashboardView;
7
6
  isEdit?: boolean;
8
7
  onClose?: (dashboard: DashboardView) => void;
9
- onDetails?: (dashboard: DashboardView) => void;
10
8
  onDuplicated?: (dashboard: DashboardView, isDone?: boolean) => void;
11
9
  onFavorite?: (id: string, value: boolean) => void;
12
10
  onStatusChanged?: (dashboard: DashboardView) => void;
@@ -14,7 +12,6 @@ interface DashboardActionsCommonProps {
14
12
  }
15
13
  interface DashboardActionsProps extends DashboardActionsCommonProps {
16
14
  applications: ApplicationModel[];
17
- categories: AllCategories;
18
15
  }
19
- declare function DotDashboardActions({ applications, categories, dashboard, isEdit, canEdit, onClose, onFavorite, onStatusChanged, onDuplicated, onViewMode, onDetails, }: DashboardActionsProps): import("react/jsx-runtime").JSX.Element;
16
+ declare function DotDashboardActions({ applications, dashboard, isEdit, canEdit, onClose, onFavorite, onStatusChanged, onDuplicated, onViewMode, }: DashboardActionsProps): import("react/jsx-runtime").JSX.Element;
20
17
  export { DashboardActionsCommonProps, DotDashboardActions };
@@ -1,10 +1,8 @@
1
1
  import { ApplicationModel } from '../../core-api/openapi';
2
- import { AllCategoriesResponse, DashboardView } from '../metadata-api/openapi';
2
+ import { DashboardView } from '../metadata-api/openapi';
3
3
  interface DashboardPublishConfirmProps {
4
4
  /** List of applications the dashboard can be published to **/
5
5
  applicationList: ApplicationModel[];
6
- /** Categories for dashboard publishing **/
7
- categories: AllCategoriesResponse;
8
6
  /** Dashboard to confirm publishing for **/
9
7
  dashboardToPublish: DashboardView;
10
8
  /** Dashboard to confirm unpublishing for **/
@@ -14,5 +12,5 @@ interface DashboardPublishConfirmProps {
14
12
  /** When a dashboard is updated, this function is called with the updated dashboard **/
15
13
  onStatusChanged: (updatedDashboard: DashboardView) => void;
16
14
  }
17
- export declare function DotDashboardPublishConfirm({ applicationList, categories, dashboardToPublish, dashboardToUnpublish, onClose, onStatusChanged, }: Readonly<DashboardPublishConfirmProps>): import("react/jsx-runtime").JSX.Element;
15
+ export declare function DotDashboardPublishConfirm({ applicationList, dashboardToPublish, dashboardToUnpublish, onClose, onStatusChanged, }: Readonly<DashboardPublishConfirmProps>): import("react/jsx-runtime").JSX.Element;
18
16
  export {};
@@ -0,0 +1,5 @@
1
+ import { AutoCompleteProps } from '../../auto-complete';
2
+ export interface DashboardCategoriesAutoCompleteProps extends AutoCompleteProps {
3
+ onNewCategory: (newCategory: string) => void;
4
+ }
5
+ export declare function DashboardCategoriesAutoComplete({ freesolo, actionItem, onInputChange, onNewCategory, ...args }: Readonly<DashboardCategoriesAutoCompleteProps>): import("react/jsx-runtime").JSX.Element;
@@ -1,5 +1,5 @@
1
1
  import { ReactNode } from 'react';
2
- import { ApiError, AllCategoriesResponse, DashboardView, DashboardCopyBody, DashboardPatchBody } from './openapi';
2
+ import { ApiError, AllCategoriesResponse, Author, DashboardView, DashboardCopyBody, DashboardPatchBody } from './openapi';
3
3
  export interface MetadataApiProviderProps {
4
4
  accountOverrideId?: string;
5
5
  apiUrl: string;
@@ -7,14 +7,14 @@ export interface MetadataApiProviderProps {
7
7
  token?: string;
8
8
  }
9
9
  interface DotMetadataApiContextProps {
10
- categories: AllCategoriesResponse;
11
- categoriesLoading: boolean;
12
10
  dashboardsError: ApiError;
13
11
  dashboardsLoading: boolean;
14
12
  duplicateDashboard: (dashboardId: string, dashboard: DashboardCopyBody) => Promise<DashboardView>;
15
13
  favoriteDashboard: (dashboardId: string, favoriteValue: boolean) => Promise<DashboardView>;
16
- getCategories: () => Promise<AllCategoriesResponse>;
14
+ getAuthors: (appType: string, publishedOnly?: boolean) => Promise<Author[]>;
15
+ getCategories: (appType: string, publishedOnly?: boolean) => Promise<string[]>;
17
16
  getDashboardHelpContent: (helpContentId: string) => Promise<string>;
17
+ metadataLoading: boolean;
18
18
  openedDashboardDetails: DashboardView;
19
19
  platformConsoleUrl: string;
20
20
  searchDashboards: (search: DashboardFilters) => Promise<DashboardView[]>;
@@ -88,17 +88,17 @@ export type DashboardView = {
88
88
  */
89
89
  favorite: boolean;
90
90
  /**
91
- * The date and time that the dashboard was last modified.
92
- */
93
- updated_dt?: string | null;
94
- /**
95
- * The full name of the dashboard modifier.
91
+ * The full name of the dashboard updated_by.
96
92
  */
97
93
  updated_by_fullname?: string | null;
98
94
  /**
99
- * The platform id of the dashboard modifier.
95
+ * The platform id of the dashboard updated_by.
100
96
  */
101
97
  updated_by_id?: string | null;
98
+ /**
99
+ * Timestamp of the latest modification
100
+ */
101
+ updated_dt?: string | null;
102
102
  };
103
103
  export declare namespace DashboardView {
104
104
  /**
@@ -2,6 +2,6 @@ export type Origin = {
2
2
  name: string;
3
3
  description: string;
4
4
  created_dt?: string | null;
5
+ is_platform_origin?: boolean;
5
6
  id?: string | null;
6
- origin_family?: Array<string> | null;
7
7
  };
@@ -15,8 +15,8 @@ export declare class DashboardsService {
15
15
  * @param sort Sort ordering to apply to the query.
16
16
  * @param filter List of filters (each filter is a separate query param, and they are OR'ed).
17
17
  *
18
- * * **Filterable field names**: author_fullname, author_id, bi_type, categories, created_dt, description, external_embedding_id, external_id, id, is_ootb_dashboard, lifecycle_state, name, target_apps, updated_dt
19
- * * **Searchable field names**: author_fullname, categories, description, name
18
+ * * **Filterable field names**: author_fullname, author_id, bi_type, categories, created_dt, description, external_embedding_id, external_id, id, is_ootb_dashboard, lifecycle_state, name, target_apps, updated_by_fullname, updated_by_id, updated_dt
19
+ * * **Searchable field names**: author_fullname, categories, description, name, updated_by_fullname
20
20
  *
21
21
  * @param favorite Boolean flag to only return dashboards marked as favorites.
22
22
  * @param q Case-insensitive search of all text fields.
@@ -112,14 +112,19 @@ export declare class DashboardsService {
112
112
  static deleteDashboardsService1(dashboardId: string): Promise<DashboardView | Error>;
113
113
  /**
114
114
  * Get Metadata (categories and authors)
115
- * Return all Metadata for the given query parameters: bi_type, lifecycle_state, target_app, and/or is_ootb_dashboard
115
+ * Return all Metadata for dashboards optionally filtered by the given parameters
116
+ * @param filter List of filters (each filter is a separate query param, and they are OR'ed).
117
+ *
118
+ * * **Filterable field names**: author_fullname, bi_type, categories, created_dt, description, is_ootb_dashboard, lifecycle_state, name, updated_by_fullname, updated_dt
119
+ * * **Searchable field names**: author_fullname, categories, description, name
120
+ *
121
+ * @param targetApp String match on the Dashboard target application - 'AGILITY', 'CONTINUOUSTEST', 'DEPLOY', 'RELEASE' or 'TEAMFORGE'.
116
122
  * @param biType String match on Dashboard bi type - 'MICROSTRATEGY'.
117
123
  * @param isOotbDashboard Boolean match on Dashboard OOTB status.
118
124
  * @param lifecycleState String match on Dashboard lifecycle state - 'DRAFT' or 'PUBLISHED'.
119
- * @param targetApp String match on the Dashboard target application - 'AGILITY', 'CONTINUOUSTEST', 'DEPLOY' or 'RELEASE'.
120
125
  * @returns MetadataResponse OK
121
126
  * @returns Error Default error response
122
127
  * @throws ApiError
123
128
  */
124
- static getDashboardsService2(biType?: string, isOotbDashboard?: boolean, lifecycleState?: string, targetApp?: string): Promise<MetadataResponse | Error>;
129
+ static getDashboardsMetadata(filter?: Array<string>, targetApp?: string, biType?: string, isOotbDashboard?: boolean, lifecycleState?: string): Promise<MetadataResponse | Error>;
125
130
  }
@@ -10,13 +10,14 @@ export declare class OriginsService {
10
10
  * @param sort Sort ordering to apply to the query.
11
11
  * @param name String match on Origin name.
12
12
  * @param description String match on Origin description.
13
+ * @param isPlatformOrigin Select from platform or tenant (non-platform) Origin.
13
14
  * @param q Case-insensitive search of all text fields.
14
15
  * @param id
15
16
  * @returns OriginPagedResponse OK
16
17
  * @returns Error Default error response
17
18
  * @throws ApiError
18
19
  */
19
- static getOriginsService(start?: number, count?: number, sort?: string, name?: string, description?: string, q?: string, id?: string): Promise<OriginPagedResponse | Error>;
20
+ static getOriginsService(start?: number, count?: number, sort?: string, name?: string, description?: string, isPlatformOrigin?: boolean, q?: string, id?: string): Promise<OriginPagedResponse | Error>;
20
21
  /**
21
22
  * Create an Origin.
22
23
  * Creates an Origin, owned by the authenticated API user.